﻿/***********************************************************************************
 * This is a demonstration program on how to use this version 1.0.0.1 of my uIP driver 
 * port for C# and NETMF on a Netduino (mini). Please note that the driver code
 * supplied is in a very early stage and haven't been propely tested yet.
 * 
 * You are free to use this program as you see fit as long as you 
 * maintain this banner. The driver code is subject of GPL V2
 * license as described in the corresponding files ENC28J60.c.cs 
 * and ENC28J60.h.cs respectively.
 * 
 * With thanks to Andreas Dunkel, Pascal Stang, Guido Socher and 
 * Guenther Hoelzl for there work prior to this.
 * 
 * All the best!
 * 
 * hanzibal, March 2011
 * 
 * ********************************************************************************/
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;

namespace ENC28J60_uIP_driver_test
{
    public class Program
    {
        public static void Main()
        {
            // TODO: change this to a MAC address of your own !!
            byte[] mac = { 0x00, 0x1e, 0xc0, 0x01, 0xb4, 0x6b };

            // create a new driver instance, these setting are for Netduino mini so if you got a regular,
            // change them according to you needs
            var nic = new ENC68J60.ENC68J60uIPDriver(Pins.GPIO_PIN_6, Pins.GPIO_PIN_5, Pins.GPIO_PIN_7, SPI_Devices.SPI1);

            // event handler for link status changes (i.e. up/down)
            nic.OnLinkChangedEvent += new ENC68J60.ENC68J60uIPDriver.LinkChangedEventHandler(nic_OnLinkChangedEvent);

            // event handler for incoming packet arrival
            nic.OnFrameArrived += new ENC68J60.ENC68J60uIPDriver.FrameArrivedEventHandler(nic_OnFrameArrived);

            // NOTE: Don't call any other functions until started
            nic.Start(mac);

            DBG("ENC68J60uIPDriver.RevId=" + nic.RevId.ToString());
            DBG("Link is currently " + (nic.IsLinkUp ? "up" : "down"));

            // stay here
            Thread.Sleep(Timeout.Infinite);
        }

        // event handler for link status changes
        static void nic_OnLinkChangedEvent(ENC68J60.ENC68J60uIPDriver sender, DateTime time, bool isUp)
        {
            DBG("Link is now " + (isUp ? "up :-)" : "down :-("));
        }

        // event handler for new ethernet frame arrivals
        static void nic_OnFrameArrived(ENC68J60.ENC68J60uIPDriver sender, DateTime time)
        {
            var buf = new byte[512];
            ushort len; uint size;

            // this were you would read ehternet bytes into a buffer, do frame assembly
            // for parsing but for now, we just reading off chunks
            for (size = 0; (len = sender.ReceiveFrame((ushort)buf.Length, buf)) > 0; size += len) ;

            // zero sized frames are no frames, but normally we shouldn't
            // be here if size where zero
            if (size > 0) DBG("Received frame data of length " + size.ToString());
        }

        static void DBG(string msg)
        {
            Debug.Print("################################ Program.Main[" + DateTime.Now.ToString() + "] --> " + msg);
        }
    }
}
